home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1993 / Internet Info CD-ROM (Walnut Creek) (1993).iso / networking / ip / ka9q / MacBMsrc.hqx / Mac bm Project / mac_path.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-10  |  9.6 KB  |  360 lines

  1. /* mac_path.c
  2.  * This module includes the generic path processing code for the KA9Q package, along
  3.  * with the file initialization code (executed only at startup).
  4.  */
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "mac_files.h"
  8.  
  9. #include <strings.h>
  10. #include <HFS.h>
  11.  
  12.  
  13. /* pathname
  14.  * Given a working directory and an arbitrary pathname, resolve them into
  15.  * an absolute pathname. Memory is allocated for the result, which
  16.  * the caller must free.
  17.  *
  18.  * path is prefixed by a colon:
  19.  *        cd:path is returned (leading colon from path provides the cd separator)
  20.  * path is NOT prefixed by a colon, but path contains a colon:
  21.  *        path is returned
  22.  * path does not contain a colon:
  23.  *        cd:path is returned (colon separator is generated)
  24.  *
  25.  *    The final absolute path is examined for ::; each such occurrence will "backup"
  26.  *    the path past the previous folder.
  27.  */
  28.  
  29. char *
  30. pathname(cd,path)
  31. char *cd;    /* Current working directory */
  32. char *path;    /* Pathname argument */
  33. {
  34.     int stcpm();
  35.     register char *buf;
  36.     register char *ptr;
  37.     char *dcolon();
  38.     char * ptr2;
  39.     int colon;
  40.         
  41. /* Ignore blank args and strip any leading white space on args
  42.  * note: send empty strings, not null pointers for a "blank" arg)
  43.  */
  44.  
  45.     if (cd == NULLCHAR || path == NULLCHAR)
  46.         return(NULLCHAR);
  47.     while (*cd == ' ' || *cd == '\t')
  48.         cd++;
  49.     while (*path == ' ' || *path == '\t')
  50.         path++;
  51.  
  52. /* Allocate and initialize output buffer; user must free */
  53.     
  54.     if ((buf = malloc(strlen(cd) + strlen(path)+2)) == NULLCHAR) {
  55.         printf("pathname:  could not allocate memory.\n");
  56.         return(NULLCHAR);
  57.     }
  58.  
  59. /* OK, we have:
  60.     cd        contains the working directory from our caller
  61.     path    contains the pathname to be used in the context of the above
  62.     
  63. Now we must earn our keep and resolve the above three to come out with
  64. an absolute path name. Somebody else will actually check it to insure that
  65. access is allowed. */
  66.  
  67.     if ((colon = strpos(path,PATH_DELIM)) == 0) {
  68.  
  69.     /* interpret path relative to cd, path IS prefixed */
  70.         if (strlen(cd)) {                    /* if we have a cd */
  71.             sprintf(buf,"%s",cd);            /* get cd in buf first */
  72.             if (buf[strlen(buf)-1] == PATH_DELIM)
  73.                 buf[strlen(buf)-1]=NULL;    /* drop last character */
  74.             sprintf(buf,"%s%s",buf,path);    /* use cd followed by path */
  75.         }
  76.         else {
  77.             ptr = path;                        /* drop prefix in path */
  78.             ptr++;
  79.             sprintf(buf,"%s",ptr);            /* use path less prefix*/
  80.         }
  81.     }
  82.     else {
  83.  
  84.     /* interpret path relative to cd, path is NOT prefixed */
  85.         if (strlen(cd) && (colon ==-1)) {    /* if we have a cd  and no other colons */
  86.             sprintf(buf,"%s",cd);            /* get cd in buf first */
  87.             if (buf[strlen(buf)-1] == PATH_DELIM)
  88.                 buf[strlen(buf)-1]=NULL;    /* drop last character */
  89.             sprintf(buf,"%s:%s",buf,path);    /* use cd followed by path */
  90.         }
  91.         else
  92.             sprintf(buf,"%s",path);            /* use path as-is */
  93.     }    
  94.     
  95. /* Special case: null final path means the application root directory */
  96.  
  97.     if (buf[0] == NULL)
  98.         sprintf(buf,"%s",applroot);    
  99.  
  100. /* now, examine what we are about to return to process double colons */
  101.  
  102.     if ((ptr2 = dcolon(buf)) != NULLCHAR) {
  103.         *ptr2 = NULL;                /* early-terminate buf */
  104.         ptr2++;                    /* ptr2 is the second part of buf, includes 1 colon */
  105.         if ((ptr = rindex(buf,PATH_DELIM)) == NULLCHAR)
  106.             strcpy(buf,ptr2);
  107.         else
  108.             strcpy(ptr,ptr2);        /* copy part after ptr2 to replace last colon */
  109.     }
  110.     return(buf);
  111. }
  112.  
  113. /* find_dcolon
  114.  *    search a string for the first occurrence of a double colon.
  115.  */
  116.  
  117. char *
  118. dcolon(string)
  119. char *string;
  120.  
  121. {
  122.     char *colon,*ptr;
  123.     
  124.     if (string == NULLCHAR)            /* can't work without data */
  125.         return(NULLCHAR);
  126.  
  127.     ptr = string;
  128.     while ((colon = index(ptr,PATH_DELIM)) != NULLCHAR) {
  129.         colon++;
  130.         if (*colon == NULL)
  131.             return(NULLCHAR);
  132.         if (*colon == PATH_DELIM) {
  133.             colon--;
  134.             return(colon);
  135.         }
  136.         ptr = colon;
  137.     }
  138.     /* no double colon seen, so exit */
  139.     return(NULLCHAR);
  140. }
  141.         
  142. /* mac_files
  143.  * Handle the one-time initialization needed for the Macintosh file names.
  144.  * Entry with flag == 1 will remove any MLMxxxx files from the application root
  145.  * Entry with flag == 0 will not remove any preexisting files.
  146.  */
  147.  
  148. int
  149. mac_files(flag)
  150. int flag;
  151. {
  152.     int MyVRefNum, e;
  153.     int len;
  154.     char buf[256],delname[256];
  155.     char *cp,*GetPathname(),*GetVolumename();
  156.     FILE *fp,*dir();
  157.     
  158. /*
  159.  * Get the path to the folder where we started NET and save in applroot
  160.  * (since we are called shortly after application launch, the default working
  161.  * directory is still set to the folder from which the application was launched).
  162.  */
  163.     GetVolumename(NULL,&MyVRefNum);        /* get default volume reference number */
  164.     GetPathname(applroot,MyVRefNum);    /* get default path name */
  165.  
  166. /* have basic path info, now generate the derivative path names */
  167.     
  168.     check_len(MAILSPOOL);
  169.     sprintf(mailspool,"%s%s", applroot, MAILSPOOL);
  170.  
  171.     check_len(MAILQDIR);
  172.     sprintf(mailqdir,"%s%s", applroot, MAILQDIR);
  173.  
  174.     check_len(ALIAS);
  175.     sprintf(alias,"%s%s", applroot, ALIAS);
  176.  
  177.     check_len(TEMPPATH);
  178.     sprintf(temppath,"%s%s", applroot, TEMPPATH);
  179.  
  180.     check_len(DIRBM);
  181.     sprintf(dirbm,"%s%s", applroot, DIRBM);
  182.     
  183. /*
  184.  * all the fixed locations have been written, now run through some of the folders
  185.  * looking for left-over files that we will delete before real startup.
  186.  */
  187.     if (flag == 0)
  188.         return(0);        /* first see if we are supposed to delete files */
  189.     
  190.     /* look for MLMxxxxx files in the application root folder */
  191.  
  192.     fp = dir(temppath,0);                        /* delete all MLM files */
  193.     if ( fp == NULLFILE)    /* Check for existence of applroot */    
  194.     {
  195.         printf("mac_path: could not find application folder.\n");
  196.         exit(-1);    
  197.     }
  198.      while (fgets(buf,sizeof(buf),fp),!feof(fp)){
  199.         if ((cp = index(buf,'\n')) == NULLCHAR)
  200.             continue;
  201.         *cp = NULL;        /* set to null string */
  202.         if ((cp = index(buf,'M')) != 0) {
  203.             if (strncmp(cp,"MLM",3) == 0) {
  204.                 sprintf(delname,"%s%s",temppath,buf);
  205.                 unlink(delname);
  206.                 continue;            /* Delete MLM files */
  207.             }
  208.         }
  209.     }
  210.     if (feof(fp)) {
  211.         /* have deleted any MLM files, now close and continue */
  212.         fclose(fp);
  213.         unlink(dirbm);        /* delete the dirbm.temp file */
  214.     }
  215.     return(0);
  216. }
  217.  
  218. /* check_len
  219.  * handle length checking for our path names in a rather specialized manner.
  220.  */
  221.  
  222. check_len(str)
  223. char *str;
  224. {
  225.     if ( (strlen(applroot) + strlen(str)) > 255 ) {
  226.         printf("Pathname to %s (max is 255) is to long, please shorten the path.\n", str);
  227.         printf("The pathname you attempted was %s%s\n", applroot, str);
  228.         exit(1);
  229.     }
  230. }
  231.  
  232. /* GetPathname
  233.  *
  234.  * This routine is passed either a working directory reference number or a volume
  235.  * reference number, and a pointer to a string. For a WDRefNum, the full path of
  236.  * the directory is returned (with trailing colon). For a VRefNum, the name of the
  237.  * volume or of the default working directory on that volume will be returned
  238.  * (with a trailing colon).
  239.  *
  240.  * Note that the string must be able to handle storage of up to 255 characters.
  241.  *
  242.  * modified from Mike Schuster, "Programming for HFS Compatibility ", 
  243.  * The Complete MacTutor, Vol. 2, pg. 87.
  244.  *
  245.  * (Mac C) to Light Speed C translation by Jeff Meredith 12/88
  246.  *
  247.  * additional documentation Edwin (Ned) Kroeker, N1EWB, 1/89
  248.  *
  249.  * Changes. 
  250.  * 1. removed requirement to pass size of wdrefnum(sizeof(wdrefnum)) as the
  251.  *    third parameter.
  252.  * 2. removed need for strntac() which is not in LSC libraries.
  253.  * 3. minor typecasting changes to match LSC prototypes.
  254.  * 4. FSFCBLen defined in HFS.h, no need to define here. If we detect MFS only,
  255.  *    we'll handle (FSFCBLen == -1 for MFS, == length of fcb for HFS)
  256.  * 5. All paths now return a trailing colon rather than no colon.
  257.  */
  258.  
  259. #define mfsSigWord 0xd2d7
  260. #define hfsSigWord 0x4244
  261. #define rootDirID 2
  262.  
  263. char *GetPathname(pname,wdrefnum)
  264. char *pname;
  265. int wdrefnum;
  266. {
  267.     HVolumeParam vp;
  268.     WDPBRec wp;
  269.     DirInfo dp;
  270.     char dname[256];
  271.     char *strtac(),*cp;
  272.  
  273. /* initialize parameters */
  274.     pname[0] = NULL;
  275.  
  276.     vp.ioNamePtr=(StringPtr)&dname;
  277.     vp.ioVRefNum=wdrefnum;
  278.     vp.ioVolIndex=0;
  279.     wp.ioNamePtr=0L;
  280.     wp.ioVRefNum=wdrefnum;
  281.     wp.ioWDIndex=0;
  282.     wp.ioWDProcID=0L;
  283.     dp.ioNamePtr=(StringPtr)&dname;
  284.     dp.ioFDirIndex=-1;
  285.  
  286. /* get volume information */
  287.  
  288.     if(!PBHGetVInfo(&vp,0))
  289.     /*
  290.      * if MFS or HFS root, return volume name only
  291.      */
  292.         if(FSFCBLen==-1||vp.ioVSigWord==mfsSigWord||vp.ioVRefNum==wdrefnum) {
  293.             strcat(pname,PtoCstr((Ptr)vp.ioNamePtr));
  294.             strcat(pname,":");
  295.         }
  296.  
  297. /* get working directory information */
  298.  
  299.     else if (!PBGetWDInfo(&wp,0)) {
  300.     
  301.     /* traverse path from working directory to root */
  302.         dp.ioVRefNum=wp.ioWDVRefNum;
  303.         dp.ioDrParID=wp.ioWDDirID;
  304.         do
  305.        {
  306.            /* get next node information */
  307.             dp.ioDrDirID=dp.ioDrParID;
  308.             if(PBGetCatInfo(&dp,0))
  309.                 break;
  310.                 
  311.             /*concatenate node name to result*/
  312.             strtac(pname,":");
  313.             strtac(pname,PtoCstr((Ptr)dp.ioNamePtr));
  314.         }
  315.         while(dp.ioDrDirID!=rootDirID);
  316.     }
  317.     /* Translate entire buffer to lower case (we do comparisons later) */
  318.     for(cp = pname;*cp != '\0';cp++)
  319.         *cp = tolower(*cp);
  320.     return(pname);
  321. }
  322.  
  323. /* GetVolumename
  324.  * This routine returns the volume name and reference number of the current default
  325.  * volume. This routine will function on both MFS and HFS systems. The string passed
  326.  * must be able to handle up to the maximum 255 character limit. If a null pointer
  327.  * is passed instead of the string, only the volume reference number is returned.
  328.  */
  329.  
  330.  char *GetVolumename(vname,vrefnum)
  331.  char *vname;
  332.  int *vrefnum;
  333.  {
  334.      WDPBRec DefDisk;
  335.      char *cp;
  336.      
  337. /* initialize parameters */
  338.      
  339.      if (vname == NULLCHAR)
  340.          DefDisk.ioNamePtr = NULL;
  341.      else
  342.          DefDisk.ioNamePtr = (StringPtr) vname;
  343.      
  344.      if ( (PBHGetVol(&DefDisk,FALSE) ) != 0) {
  345.         printf("Could not get the volume path name.\n");
  346.         exit(-1);    
  347.     }
  348.  
  349.     *vrefnum = DefDisk.ioVRefNum;        /* copy the volume reference number */
  350.     if (DefDisk.ioNamePtr != NULL) {
  351.         PtoCstr(vname);                    /* convert name string to C */
  352.     /* Translate entire buffer to lower case (we do comparisons later) */
  353.         for(cp = vname;*cp != '\0';cp++)
  354.             *cp = tolower(*cp);
  355.         return(vname);
  356.     }
  357.     else
  358.         return (NULLCHAR);
  359. }
  360.